package metamap.proxy.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;

import metamap.proxy.server.jaxws.MetamapProxyService;
import metamap.proxy.server.jaxws.MetamapService;

public class MetamapClient {
	private static ExecutorService executor;
	private URL url;
	MetamapProxyService service;
	static MetamapService port;

	public MetamapClient(String service_adress) throws MalformedURLException {
		url = new URL(service_adress);
		String wsdlname = url.getFile();
		if (wsdlname.equals("") || wsdlname == null) {
			System.out.println(service_adress + " non è valido");
			System.exit(2);
		}
		service = new MetamapProxyService(url, new QName(
				"http://jaxws.server.proxy.metamap/",
				"MetamapServiceImplService"));
		port = service.getMetaMapPort();
		executor = Executors.newFixedThreadPool(20);
	}
/**
 * Blocking method that retrieve the preferred names from the service
 * @param term The text to get mapped
 * @return a List<String> containing the preferred names
 */
	public static List<String> blockingQuery(String term) {
		List<String> gruppi = new LinkedList<String>();
		gruppi.add("CHEM");
		gruppi.add("GENE");
		List<String> output = port.getPreferredNames(term, gruppi);
		// System.out.println("Effettuata query al server Metamap, ottenuti "+output.size()+" risultati");
		return output;

	}
/**
 * This method provides a way to asynchronously call the metamap service,
 * using a worker thread. Each instance of MetamapClient share the same limit of
 * thread, this method will block this limit is reached
 * the Future will contain the result
 * @param text The text to get meta-mapped
 * 
 * @return a Future of List<String> containing the results
 */
	public static Future<List<String>> delayedQuery(String text) {

		Worker w = new Worker(text);
		Future<List<String>> out = executor.submit(w);
		return out;
	}
}
/**
 * Worker class used by the MetamapClient, each instance is executed in a separated thread
 * @author melo
 *
 */
class Worker implements Callable<List<String>> {
	private String text;

	public Worker(String s) {
		text = s;
	}

	public Worker(BufferedReader br) {
		String line;
		StringBuffer result = new StringBuffer();
		try {
			while ((line = br.readLine()) != null) {
				result.append(line);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		text = result.toString();
	}

	@Override
	public List<String> call() {
		return MetamapClient.blockingQuery(text);

	}

}
